const { chromium } = require('playwright');
const fs = require('fs/promises');
const path = require('path');
const { URL } = require('url');

class Recorder {
  constructor(storagePath) {
    this.storagePath = storagePath;
    this.apiCalls = [];
    this.userActions = [];
  }

  async startRecording(url) {
    // 初始化浏览器
    this.browser = await chromium.launch({ headless: false });
    this.page = await this.browser.newPage();
    
    // 设置监听器
    await this.setupListeners();
    
    // 导航到目标URL
    await this.page.goto(url);
    
    // 创建存储目录
    const dirName = this.getRecordingDirName(url);
    this.recordingDir = path.join(this.storagePath, dirName);
    await fs.mkdir(this.recordingDir, { recursive: true });
    
    // 保存初始HTML
    await this.captureHtmlSnapshot('initial');
  }

  async setupListeners() {
    // API请求拦截
    await this.page.route('**', route => {
      const request = route.request();
      this.recordApiCall(request);
      route.continue();
    });

    // DOM变化监听
    await this.page.exposeFunction('onDomChange', (change) => {
      this.userActions.push({
        type: 'DOM_CHANGE',
        timestamp: new Date().toISOString(),
        data: change
      });
    });

    // 用户操作监听
    await this.page.addListener('click', event => {
      this.userActions.push({
        type: 'CLICK',
        timestamp: new Date().toISOString(),
        data: {
          x: event.pageX,
          y: event.pageY,
          selector: event.target?.toString()
        }
      });
    });
  }

  async recordApiCall(request) {
    const response = await request.response();
    if (!response) return;

    this.apiCalls.push({
      request: {
        url: request.url(),
        method: request.method(),
        headers: request.headers(),
        postData: request.postData()
      },
      response: {
        status: response.status(),
        headers: response.headers(),
        body: await response.text().catch(() => null)
      },
      timestamp: new Date().toISOString()
    });
  }

  async captureHtmlSnapshot(name) {
    const html = await this.page.content();
    await fs.writeFile(
      path.join(this.recordingDir, `${name}.html`),
      html
    );
  }

  getRecordingDirName(url) {
    const parsedUrl = new URL(url);
    const host = parsedUrl.hostname.replace(/\./g, '_');
    const path = parsedUrl.pathname.replace(/\//g, '_') || 'root';
    return `${host}_${path}_${Date.now()}`;
  }

  async stopRecording() {
    // 保存最终HTML
    await this.captureHtmlSnapshot('final');
    
    // 保存API调用
    const apiDir = path.join(this.recordingDir, 'api');
    await fs.mkdir(apiDir, { recursive: true });
    
    for (const [i, call] of this.apiCalls.entries()) {
      await fs.writeFile(
        path.join(apiDir, `request_${i}.json`),
        JSON.stringify(call.request, null, 2)
      );
      await fs.writeFile(
        path.join(apiDir, `response_${i}.json`),
        JSON.stringify(call.response, null, 2)
      );
    }
    
    // 保存用户操作
    await fs.writeFile(
      path.join(this.recordingDir, 'actions.json'),
      JSON.stringify(this.userActions, null, 2)
    );
    
    // 保存元数据
    await fs.writeFile(
      path.join(this.recordingDir, 'metadata.json'),
      JSON.stringify({
        createdAt: new Date().toISOString(),
        url: this.page.url(),
        duration: Date.now() - this.startTime,
        stats: {
          apiCalls: this.apiCalls.length,
          userActions: this.userActions.length
        }
      }, null, 2)
    );
    
    // 关闭浏览器
    await this.browser.close();
    
    return {
      recordingDir: this.recordingDir,
      stats: {
        apiCalls: this.apiCalls.length,
        userActions: this.userActions.length
      }
    };
  }
}

module.exports = Recorder;